﻿using Microsoft.VisualStudio.TestTools.UITest.Common;
using Microsoft.VisualStudio.TestTools.UITest.Extension;
using System.Windows.Forms;
namespace AXExtension.Filters
{
	/// <summary>
	/// Makes segmented entry filters usable and
	/// performant by interpreting the intent of users
	/// and recording it as simple text typing 
	/// actions.
	/// </summary>
	class SegmentedEntryFilter : Filter
	{
		private IUITechnologyElement target;

		public SegmentedEntryFilter()
		{
			Require(stack => {
				return stack.Peek().ActionName == "Left Click" &&
					stack.Peek().UIElement.ClassName == "Uia.TextBlock" &&
					stack.Peek().UIElement.QueryId.Ancestor.ClassName == "Uia.ContentPresenter";
			});
		}

		public override void UnconditionalRun(IUITestActionStack stack)
		{
			AXUtils.LoadManager("UIA");
			if(target == null &&
				stack.Count > 0 &&
				stack.Peek().UIElement != null && 
				stack.Peek().ActionName == "Left Click" &&
				stack.Peek().UIElement.ClassName == "Uia.Button" &&
				stack.Peek().UIElement.Name == "")
			{
				UITechnologyElement button = stack.Peek().UIElement;
				var children = button.Parent().Children();
				foreach (var child in children)
				{
					if (child.GetRequestedState(AccessibleStates.Focused) != AccessibleStates.Default)
					{
						target = child;
						break;
					}
				}
			}
		}

		public override void Run(IUITestActionStack stack)
		{
			IUITechnologyElement element = stack.Peek().UIElement;

			AXUtils.LoadManager("UIA");

			// If we're clicking on the whole row, we can just
			// go down to the first column's value.
			if(element.ControlTypeName == "DataItem")
			{
				RecreateAsTyping(stack, element.Child(0).Child(0).Name);
				return;
			}

			// Otherwise we must be clicking on some column in
			// the row, so we can go up to the whole row, and
			// back down to the first column.
			element = element.Parent().Parent().Child(0).Child(0);
			RecreateAsTyping(stack, element.Name);
		}

		private void RecreateAsTyping(IUITestActionStack stack,  string value)
		{
			stack.Pop();
			while(stack.Count >= 2 &&
				stack.Peek().UIElement != null &&
				stack.Peek().UIElement.ClassName == "Uia.Button" &&
				stack.Peek().UIElement.Name == "")
			{
				stack.Pop();
			}

			if(target != null)
			{
				var sendKeys = new SendKeysAction();
				sendKeys.Text = "{Ctrl}{Left}{Shift}{Ctrl}{Right}" + value + "{Tab}";
				stack.Push(sendKeys);
				target = null;
			}
		}
	}
}
